package org.superheroes.androidclient.gui;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

import org.superheroes.androidclient.enums.State;
import org.superheroes.androidclient.net.Client;
import org.superheroes.androidclient.packets.RTPPacket;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

/**
 * The Main Activity Don't forget to forward the UDP port!
 * 
 * command prompt/terminal: telnet localhost 5554 redir add udp:25000:25000
 * 
 * @author Jeffrey Goudzwaard
 * @author Davin Terrizi
 * @version 1.0
 */
public class ClientActivity extends Activity
{
	// The tag for debugging
	private static final String	LOG_TAG			= ClientActivity.class.getName();

	// The buttons on the screen
	private Button				btnSetup;
	private Button				btnPlay;
	private Button				btnPause;
	private Button				btnTeardown;

	// The image view, for the movie
	private ImageView			imgView;

	// The thread for updating the movie and receiving UDP packets
	private Thread				timerThread;

	// If the timerThread is running
	private boolean				running			= false;

	// The client thread, for the TCP connection
	private Thread				clientThread	= new Thread( new Runnable()
												{

													@Override
													public void run()
													{
														Client.getCLient().start();
													}
												} );

	/**
	 * Starts the timer thread, creating a new timer thread every time this function is called
	 * because you can't start a timer after you cancled it.
	 */
	public void startTimer()
	{
		running = true;

		timerThread = new Thread( new Runnable()
		{

			@Override
			public void run()
			{
				while ( running )
				{
					Client client = Client.getCLient();

					client.setDatagramPacket( new DatagramPacket( client.getBuffer(), client.getBuffer().length ) );
					try
					{
						client.getUDPSocket().receive( client.getDataGramPacket() );
					}
					catch ( IOException e )
					{
						Log.e( LOG_TAG, e.toString() );
					}

					RTPPacket packet = new RTPPacket( client.getDataGramPacket().getData(), client.getDataGramPacket().getLength() );
					client.setRTPPacket( packet );

					int payloadLenght = client.getRTPPacket().getPayloadLength();
					byte[] payload = new byte[ payloadLenght ];

					Log.i( "Payload", payloadLenght + "" );

					client.getRTPPacket().getPayload( payload );

					for ( int i = 0; i < payloadLenght; i++ )
					{
						Log.i( "Payload", payload[ i ] + "" );
					}

					final Bitmap bmp = BitmapFactory.decodeByteArray( payload, 0, payloadLenght );

					runOnUiThread( new Runnable()
					{

						@Override
						public void run()
						{
							imgView.setImageBitmap( bmp );
						}
					} );

					try
					{
						Thread.sleep( 20 );
					}
					catch ( InterruptedException e )
					{
						Log.e( LOG_TAG, e.toString() );
					}
				}
			}
		} );

		timerThread.start();
	}

	// Stopping the timer thread
	public void stopTimer()
	{
		running = false;

		timerThread.interrupt();
	}

	@Override
	protected void onCreate( Bundle savedInstanceState )
	{
		super.onCreate( savedInstanceState );
		setContentView( R.layout.activity_client );

		initControls();

		clientThread.start();
	}

	@Override
	public boolean onCreateOptionsMenu( Menu menu )
	{
		getMenuInflater().inflate( R.menu.client, menu );
		return true;
	}

	/**
	 * Initialize the buttons
	 */
	private void initControls()
	{
		btnSetup = ( Button ) findViewById( R.id.btnSetup );
		btnSetup.setOnClickListener( new OnClickListener()
		{

			@Override
			public void onClick( View v )
			{
				Log.i( LOG_TAG, "Button SETUP pressed!" );
				btnSetup();
			}
		} );

		btnPlay = ( Button ) findViewById( R.id.btnPlay );
		btnPlay.setOnClickListener( new OnClickListener()
		{

			@Override
			public void onClick( View v )
			{
				Log.i( LOG_TAG, "Button PLAY pressed!" );
				btnPlay();
			}
		} );

		btnPause = ( Button ) findViewById( R.id.btnPause );
		btnPause.setOnClickListener( new OnClickListener()
		{

			@Override
			public void onClick( View v )
			{
				Log.i( LOG_TAG, "Button PAUSE pressed!" );
				btnPause();
			}
		} );

		btnTeardown = ( Button ) findViewById( R.id.btnTeardown );
		btnTeardown.setOnClickListener( new OnClickListener()
		{

			@Override
			public void onClick( View v )
			{
				Log.i( LOG_TAG, "Button TEARDOWN pressed!" );
				btnTeardown();
			}
		} );

		imgView = ( ImageView ) findViewById( R.id.imageView1 );
	}

	// The action that need to be done when clicked on the setup button
	private void btnSetup()
	{
		Thread t = new Thread( new Runnable()
		{

			@Override
			public void run()
			{
				Client client = Client.getCLient();

				if ( client.getState() == State.INIT )
				{
					try
					{
						// Making the UDP connection
						client.setUDPSocket( new DatagramSocket( client.getPort() ) );
						client.getUDPSocket().setSoTimeout( 5 );
					}
					catch ( IOException e )
					{
						Log.e( LOG_TAG, e.toString() );
					}

					client.setSeqnr( 1 );

					client.sendRequest( State.SETUP );

					int serverResponse = client.parseServerResponse();

					if ( serverResponse != 200 )
					{
						Log.e( LOG_TAG, "Server response was not 200 (OK)" );
					}
					else
					{
						client.setState( State.READY );
						Log.i( LOG_TAG, "New RTSP State: READY" );
					}
				}
			}
		} );

		t.start();
	}

	// The action that need to be done when clicked on the play button
	private void btnPlay()
	{
		Thread t = new Thread( new Runnable()
		{

			@Override
			public void run()
			{
				Client client = Client.getCLient();

				if ( client.getState() == State.READY )
				{
					client.sendRequest( State.PLAY );

					if ( client.parseServerResponse() != 200 )
					{
						Log.e( LOG_TAG, "Server response was not 200 (OK)" );
					}
					else
					{
						startTimer();
						client.setState( State.PLAYING );
						Log.i( LOG_TAG, "New RTSP State: PLAYING" );
					}
				}
			}
		} );

		t.start();
	}

	// The action that need to be done when clicked on the pause button
	private void btnPause()
	{
		Thread t = new Thread( new Runnable()
		{

			@Override
			public void run()
			{
				Client client = Client.getCLient();

				if ( client.getState() == State.PLAYING )
				{
					client.sendRequest( State.PAUSE );

					if ( client.parseServerResponse() != 200 )
					{
						Log.e( LOG_TAG, "Server response was not 200 (OK)" );
					}
					else
					{
						stopTimer();
						client.setState( State.READY );
						Log.i( LOG_TAG, "New RTSP State: READY" );
					}
				}
			}
		} );

		t.start();
	}

	// The action that need to be done when clicked on the teardown button
	private void btnTeardown()
	{
		Thread t = new Thread( new Runnable()
		{

			@Override
			public void run()
			{
				Client client = Client.getCLient();

				client.sendRequest( State.TEARDOWN );

				if ( client.parseServerResponse() != 200 )
				{
					Log.e( LOG_TAG, "Server response was not 200 (OK)" );
				}
				else
				{
					stopTimer();
				}
			}
		} );

		t.start();
	}
}